package com.sojson.util;

import static com.sojson.util.cache.CacheUtil.CACHE_REDIS;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.sojson.project.sys.dict.entity.dto.DictDataDto;
import com.sojson.project.sys.dict.entity.dto.DictTypeDto;
import com.sojson.project.sys.dict.entity.vo.DictDataVo;
import com.sojson.project.sys.dict.service.DictDataService;
import com.sojson.project.sys.dict.service.DictTypeService;

/**
 * 字典工具类
 *
 * @author lyh
 */
public class DictUtil {

    private static DictTypeService dictTypeService = SpringUtil.getBeanByType(DictTypeService.class);
    private static DictDataService dictDataService = SpringUtil.getBeanByType(DictDataService.class);
    /** 字典缓存集合在缓存中的名字 */
    public static final String MAP_KEY = "dict_param_map";
    /** 分隔符 */
    public static final String SEPARATOR = ",";

    /**
     * 加载字典缓存
     *
     * @param key
     * @throws IOException
     */
    public static void load() throws IOException {
        put(dictDataService.list(new DictDataDto()));
    }

    /**
     * 重新加载字典缓存
     *
     * @param key
     * @throws IOException
     */
    public static void reload() throws IOException {
        // 删除缓存
        List<String> findCodeByDto = dictTypeService.findCodeByDto(new DictTypeDto());
        del(findCodeByDto);

        // 加载缓存
        load();
    }

    /**
     * 设置字典缓存
     *
     * @param vals
     * @throws IOException
     */
    public static void put(List<DictDataVo> vals) throws IOException {
        Map<String, List<DictDataVo>> hashMap = new HashMap<>();
        for (DictDataVo dictData : vals) {
            String code = dictData.getCode();
            List<DictDataVo> list = hashMap.get(code);
            if (StringUtil.isBlankObject(list)) {
                list = new ArrayList<>();
                hashMap.put(code, list);
            }

            list.add(dictData);
        }

        Set<Entry<String, List<DictDataVo>>> entrySet = hashMap.entrySet();
        for (Entry<String, List<DictDataVo>> entry : entrySet) {
            put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 设置字典缓存
     *
     * @param key       参数键
     * @param vals      字典数据列表
     * @throws IOException
     */
    public static void put(String key, List<DictDataVo> vals) throws IOException {
        CACHE_REDIS.setByMap(getCacheKey(), key, vals);
    }

    /**
     * 删除字典缓存
     *
     * @param keys
     * @throws IOException
     */
    public static void del(List<String> keys) throws IOException {
        del(keys.toArray(new String[] {}));
    }

    /**
     * 删除字典缓存
     *
     * @param keys
     * @throws IOException
     */
    public static void del(String... keys) throws IOException {
        CACHE_REDIS.delByMapKey(getCacheKey(), keys);
    }

    /**
     * 获取字典缓存
     *
     * @param key
     * @return
     * @throws IOException
     */
    public static List<DictDataVo> gets(String key) throws IOException {
        return CACHE_REDIS.getByMap(getCacheKey(), key);
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType  字典类型
     * @param dictValue 字典值
     * @return 字典标签
     * @throws IOException
     */
    public static String getDictLabel(String dictType, String dictValue) throws IOException {
        return getDictLabel(dictType, dictValue, SEPARATOR);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType  字典类型
     * @param dictLabel 字典标签
     * @return 字典值
     * @throws IOException
     */
    public static String getDictValue(String dictType, String dictLabel) throws IOException {
        return getDictValue(dictType, dictLabel, SEPARATOR);
    }

    /**
     * 根据字典类型和字典值获取字典标签
     *
     * @param dictType  字典类型
     * @param dictValue 字典值
     * @param separator 分隔符
     * @return 字典标签
     * @throws IOException
     */
    public static String getDictLabel(String dictType, String dictValue, String separator) throws IOException {
        StringBuilder propertyString = new StringBuilder();
        List<DictDataVo> datas = gets(dictType);

        if (StringUtil.containsAny(separator, dictValue) && StringUtil.isNotBlank(datas)) {
            for (DictDataVo dict : datas) {
                for (String value : dictValue.split(separator)) {
                    if (value.equals(dict.getVal())) {
                        propertyString.append(dict.getName() + separator);
                        break;
                    }
                }
            }
        } else {
            for (DictDataVo dict : datas) {
                if (dictValue.equals(dict.getVal())) {
                    return dict.getName();
                }
            }
        }
        return StringUtil.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     *
     * @param dictType  字典类型
     * @param dictLabel 字典标签
     * @param separator 分隔符
     * @return 字典值
     * @throws IOException
     */
    public static String getDictValue(String dictType, String dictLabel, String separator) throws IOException {
        StringBuilder propertyString = new StringBuilder();
        List<DictDataVo> datas = gets(dictType);

        if (StringUtil.containsAny(separator, dictLabel) && StringUtil.isNotBlank(datas)) {
            for (DictDataVo dict : datas) {
                for (String label : dictLabel.split(separator)) {
                    if (label.equals(dict.getName())) {
                        propertyString.append(dict.getVal() + separator);
                        break;
                    }
                }
            }
        } else {
            for (DictDataVo dict : datas) {
                if (dictLabel.equals(dict.getName())) {
                    return dict.getVal();
                }
            }
        }
        return StringUtil.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 设置cache key
     *
     * @return 缓存键key
     */
    public static String getCacheKey() {
        return MAP_KEY;
    }

}